Load package

library(EBImage)
## Warning: package 'EBImage' was built under R version 3.4.3
options("EBImage.display"="raster")

Read image data

img = readImage("CD3 images for counting/MS10-41192 a.tif")
## Warning in readTIFF(x, all = all, ...): TIFFReadDirectory: Unknown field
## with tag 33560 (0x8318) encountered
display(img)

Retrieve red channel and convert to grayscale

img = channel(img,"b")
colorMode(img) = Grayscale
display(img)

Global tresholding

Preprocessing step to clean up the image by removing local artifacts or noise throuth smoothing.

threshold = 0.5
img_th = combine( mapply(function(frame, th) frame > th, getFrames(img), threshold, SIMPLIFY=FALSE) )
display(img_th)

img_neg = max(img_th) - img_th

Watershed algorithm

nmask = watershed(distmap(img_neg),2)
display(colorLabels(nmask))

Image segmentation & size cutoff

seg = nmask
seg@.Data[nmask@.Data %in% which(table(nmask@.Data)<600 | table(nmask@.Data)>2500)] = 0
display(colorLabels(seg))

Quantification

length(table(seg@.Data))-1
## [1] 174

Get CD3 counts for all files

#path to files
files = list.files("CD3 images for counting/")

getCD3 = function(img,filenames){
    img = channel(img,"b")
    colorMode(img) = Grayscale
    threshold = 0.5
    img = combine( mapply(function(frame, th) frame > th, getFrames(img), threshold, SIMPLIFY=FALSE) )
    img = max(img) - img
    img = watershed(distmap(img),2)
    img@.Data[img@.Data %in% which(table(img@.Data)<600 | table(img@.Data)>3000)] = 0
    #writeImage(img, paste0("CD3_segments/",filenames,".jpeg")) 
    return(length(table(img@.Data))-1)
}

counts = sapply(1:length(files),function(x) getCD3(readImage(paste0("CD3 images for counting/",files[x])),files[x]))
write.csv(cbind(files,counts),file="counts.csv")